/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.courses.pb138.j2014.projects.soxc.GUI;

import cz.muni.fi.courses.pb138.j2014.projects.soxc.Options;
import cz.muni.fi.courses.pb138.j2014.projects.soxc.PreprocessingOptions;
import cz.muni.fi.courses.pb138.j2014.projects.soxc.Soxc;
import cz.muni.fi.courses.pb138.j2014.projects.soxc.difftree.DocumentDiffTree;
import cz.muni.fi.courses.pb138.j2014.projects.soxc.difftree.consumers.JustDocumentDiffTreeConsumer;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.filechooser.FileFilter; 
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

/**
 *
 * @author Jakub Kremláček
 */
public class GUISelector extends javax.swing.JFrame {

    /**
     * Creates new form GUIMain
     */
    public static String newline = System.getProperty("line.separator");
    
    public GUISelector() {
        initComponents();
        setLocationRelativeTo(null);
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    
    private void setPath(javax.swing.JTextField jTextField) {
        JFileChooser chooser = new JFileChooser();
        chooser.setAcceptAllFileFilterUsed(false);
        chooser.addChoosableFileFilter(new FileFilter() {
            public String getDescription() {
                return "XML Documents (*.xml)";
            }

            public boolean accept(File f) {
                if (f.isDirectory()) {
                    return true;
                } else {
                    return f.getName().toLowerCase().endsWith(".xml");
                }
            }
        });
        chooser.showOpenDialog(null);
        File f = chooser.getSelectedFile();
        String filepath = f.getAbsolutePath();
        jTextField.setText(filepath);
    }
    
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jCheckBox4 = new javax.swing.JCheckBox();
        pathfileLeft = new javax.swing.JTextField();
        leftFileLabel = new javax.swing.JLabel();
        rightFileLabel = new javax.swing.JLabel();
        pathfileRight = new javax.swing.JTextField();
        browseButtonLeft = new javax.swing.JButton();
        browseButtonRight = new javax.swing.JButton();
        selectFilesLabel = new javax.swing.JLabel();
        runButton = new javax.swing.JButton();
        checkBoxIgnoreElementOrder = new javax.swing.JCheckBox();
        checkBoxIgnoreAttrInSimilar = new javax.swing.JCheckBox();
        optionsLabel = new javax.swing.JLabel();
        checkBoxIgnoreNamespaceURI = new javax.swing.JCheckBox();
        checkBoxIgnorePrefix = new javax.swing.JCheckBox();
        jSeparator1 = new javax.swing.JSeparator();
        jSeparator2 = new javax.swing.JSeparator();
        checkBoxIgnoreElNameInSimilarity = new javax.swing.JCheckBox();
        checkBoxIgnoreWhitespaceOnlyText = new javax.swing.JCheckBox();
        checkBoxIgnoreText = new javax.swing.JCheckBox();
        checkBoxTrimWhiteSpace = new javax.swing.JCheckBox();
        jLabel1 = new javax.swing.JLabel();
        jSeparator3 = new javax.swing.JSeparator();
        checkBoxIgnoreComments = new javax.swing.JCheckBox();
        checkBoxCoalesceCDATA = new javax.swing.JCheckBox();
        checkBoxExpandEntityRefs = new javax.swing.JCheckBox();
        checkBoxIgnoreCDATA = new javax.swing.JCheckBox();
        checkBoxIgnoreProcessingInstructions = new javax.swing.JCheckBox();

        jCheckBox4.setText("jCheckBox4");

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("SOXC GUI");
        setResizable(false);

        pathfileLeft.setEditable(false);
        pathfileLeft.setText("path");

        leftFileLabel.setText("XML File 1");

        rightFileLabel.setText("XML File 2");

        pathfileRight.setEditable(false);
        pathfileRight.setText("path");

        browseButtonLeft.setText("Browse");
        browseButtonLeft.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                browseButtonLeftActionPerformed(evt);
            }
        });

        browseButtonRight.setText("Browse");
        browseButtonRight.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                browseButtonRightActionPerformed(evt);
            }
        });

        selectFilesLabel.setText("Select files:");

        runButton.setText("Run");
        runButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                runButtonActionPerformed(evt);
            }
        });

        checkBoxIgnoreElementOrder.setText("Ignore element order");
        checkBoxIgnoreElementOrder.setToolTipText("Whether to ignore order of elements");

        checkBoxIgnoreAttrInSimilar.setSelected(true);
        checkBoxIgnoreAttrInSimilar.setText("Ignore attributes in similarity");
        checkBoxIgnoreAttrInSimilar.setToolTipText("Wheter to ignore attributes (incl. values) when finding matching elements.");

        optionsLabel.setText("Additional options:");

        checkBoxIgnoreNamespaceURI.setText("Ignore namespace URI");
        checkBoxIgnoreNamespaceURI.setToolTipText("Wheter to exclude nodes' namespace URI from comparison");

        checkBoxIgnorePrefix.setText("Ignore prefix");
        checkBoxIgnorePrefix.setToolTipText("Wheter to exclude nodes' prefix from comparison");

        checkBoxIgnoreElNameInSimilarity.setToolTipText("Wheter to ignore element names (incl. namespace+prefix) when finding matching elements");
        checkBoxIgnoreElNameInSimilarity.setLabel("Ignore element name in similarity");

        checkBoxIgnoreWhitespaceOnlyText.setSelected(true);
        checkBoxIgnoreWhitespaceOnlyText.setToolTipText("Whether to exclude whitespace-only text nodes from comparison (doesn't apply to attribute values)");
        checkBoxIgnoreWhitespaceOnlyText.setLabel("Ignore whitespace-only text");

        checkBoxIgnoreText.setToolTipText("Whether to exclude text nodes from comparison");
        checkBoxIgnoreText.setLabel("Ignore text nodes");

        checkBoxTrimWhiteSpace.setToolTipText("Whether to trim whitespace in text nodes like in HTML (leading/trailing ws removed, internal ws collapsed into one space; doesn't apply to attribute values)");
        checkBoxTrimWhiteSpace.setLabel("Trim whitespace in text");

        jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/cz/muni/fi/courses/pb138/j2014/projects/soxc/GUI/img/SOXC.png"))); // NOI18N

        checkBoxIgnoreComments.setToolTipText("Whether to exclude comments from comparison");
        checkBoxIgnoreComments.setLabel("Ignore comments");

        checkBoxCoalesceCDATA.setSelected(true);
        checkBoxCoalesceCDATA.setText("Coalesce CDATA into text");
        checkBoxCoalesceCDATA.setToolTipText("Whether to coalesce CDATA sections into surrounding text nodes");

        checkBoxExpandEntityRefs.setSelected(true);
        checkBoxExpandEntityRefs.setText("Expand entity references");
        checkBoxExpandEntityRefs.setToolTipText("Whether to expand entity references before comparison");

        checkBoxIgnoreCDATA.setText("Ignore CDATA");
        checkBoxIgnoreCDATA.setToolTipText("Whether to exclude CDATA sections from comparison");

        checkBoxIgnoreProcessingInstructions.setText("Ignore processing instructions");
        checkBoxIgnoreProcessingInstructions.setToolTipText("Whether to exclude processing instructions from comparison");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(88, 88, 88)
                .addComponent(optionsLabel)
                .addGap(0, 0, Short.MAX_VALUE))
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                    .addComponent(pathfileRight)
                                    .addComponent(pathfileLeft, javax.swing.GroupLayout.Alignment.LEADING))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(browseButtonLeft, javax.swing.GroupLayout.Alignment.TRAILING)
                                    .addComponent(browseButtonRight, javax.swing.GroupLayout.Alignment.TRAILING)))
                            .addGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                        .addComponent(checkBoxTrimWhiteSpace)
                                        .addComponent(checkBoxIgnoreNamespaceURI)
                                        .addComponent(jLabel1)
                                        .addComponent(selectFilesLabel)
                                        .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, 300, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addComponent(checkBoxIgnoreAttrInSimilar, javax.swing.GroupLayout.DEFAULT_SIZE, 301, Short.MAX_VALUE)
                                        .addComponent(checkBoxIgnoreElementOrder, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                        .addComponent(jSeparator2)
                                        .addComponent(jSeparator1)
                                        .addComponent(checkBoxIgnoreText))
                                    .addComponent(runButton)
                                    .addComponent(rightFileLabel))
                                .addGap(0, 0, Short.MAX_VALUE)))
                        .addContainerGap())
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(checkBoxIgnoreCDATA)
                            .addComponent(checkBoxIgnoreProcessingInstructions)
                            .addComponent(checkBoxIgnorePrefix, javax.swing.GroupLayout.PREFERRED_SIZE, 224, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(checkBoxIgnoreElNameInSimilarity)
                            .addComponent(checkBoxExpandEntityRefs)
                            .addComponent(checkBoxCoalesceCDATA)
                            .addComponent(checkBoxIgnoreComments)
                            .addComponent(checkBoxIgnoreWhitespaceOnlyText)
                            .addComponent(leftFileLabel))
                        .addGap(0, 0, Short.MAX_VALUE))))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(1, 1, 1)
                .addComponent(selectFilesLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(leftFileLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(pathfileLeft, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(browseButtonLeft))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(rightFileLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(pathfileRight, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(browseButtonRight))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(optionsLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(checkBoxIgnoreElementOrder)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkBoxIgnoreElNameInSimilarity)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkBoxIgnoreAttrInSimilar)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkBoxIgnoreNamespaceURI)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkBoxIgnorePrefix)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkBoxIgnoreText)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkBoxIgnoreWhitespaceOnlyText)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkBoxTrimWhiteSpace)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkBoxIgnoreComments)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkBoxCoalesceCDATA)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkBoxExpandEntityRefs)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkBoxIgnoreCDATA)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkBoxIgnoreProcessingInstructions)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(runButton)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void browseButtonLeftActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonLeftActionPerformed
        setPath(pathfileLeft);
    }//GEN-LAST:event_browseButtonLeftActionPerformed

    private void browseButtonRightActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonRightActionPerformed
        setPath(pathfileRight);
    }//GEN-LAST:event_browseButtonRightActionPerformed

    private void runButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_runButtonActionPerformed
        try {
           
            if(!"path".equals(pathfileLeft.getText()) && !"path".equals(pathfileRight.getText())) {
                this.setVisible(false);
                
                // CREATE THE DOCUMENT BUILDER:
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                factory.setNamespaceAware(true); // this is necessary - /home/ondrej/Dokumenty/Developing/PB138/soxc-xml/compare1.xml
                factory.setIgnoringComments(checkBoxIgnoreComments.isSelected());
                factory.setCoalescing(checkBoxCoalesceCDATA.isSelected());
                factory.setExpandEntityReferences(checkBoxExpandEntityRefs.isSelected());
                
                DocumentBuilder builder = factory.newDocumentBuilder();
                
                // PARSE DOCUMENTS:
                Document docLeft = builder.parse(pathfileLeft.getText());
                Document docRight = builder.parse(pathfileRight.getText());
                
                // RUN THE COMPARISON:
                PreprocessingOptions preOpts = new PreprocessingOptions(
                        checkBoxIgnoreText.isSelected(),
                        checkBoxIgnoreWhitespaceOnlyText.isSelected(),
                        checkBoxTrimWhiteSpace.isSelected(),
                        checkBoxIgnoreCDATA.isSelected(),
                        checkBoxIgnoreProcessingInstructions.isSelected());

                JustDocumentDiffTreeConsumer consumer = new JustDocumentDiffTreeConsumer();
                Options options = new Options(
                        checkBoxIgnoreElementOrder.isSelected(),
                        checkBoxIgnoreElNameInSimilarity.isSelected(),
                        checkBoxIgnoreAttrInSimilar.isSelected(),
                        checkBoxIgnoreNamespaceURI.isSelected(),
                        checkBoxIgnorePrefix.isSelected());
                
                boolean equals = Soxc.diffDocumentsPreprocess(docLeft, docRight, options, preOpts, consumer);

                if (equals) {
                    String message = "XML files are equal.";
                    JOptionPane.showMessageDialog(new JFrame(), message, "SOXC", JOptionPane.INFORMATION_MESSAGE);
                    System.exit(0);
                } else {
                    DocumentDiffTree tree = consumer.getDocumentDiffTree();
                    GUIDisplay frame = new GUIDisplay(tree);
                    frame.display();
                }
            } else {
                String message = "Pathfiles have to be set.";
                JOptionPane.showMessageDialog(new JFrame(), message, "Error", JOptionPane.ERROR_MESSAGE);
            }
            
        } catch (ParserConfigurationException | SAXException | IOException ex) {
            Logger.getLogger(GUISelector.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_runButtonActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            UIManager.setLookAndFeel(
            UIManager.getSystemLookAndFeelClassName()); 
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(GUISelector.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(GUISelector.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(GUISelector.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(GUISelector.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new GUISelector().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton browseButtonLeft;
    private javax.swing.JButton browseButtonRight;
    private javax.swing.JCheckBox checkBoxCoalesceCDATA;
    private javax.swing.JCheckBox checkBoxExpandEntityRefs;
    private javax.swing.JCheckBox checkBoxIgnoreAttrInSimilar;
    private javax.swing.JCheckBox checkBoxIgnoreCDATA;
    private javax.swing.JCheckBox checkBoxIgnoreComments;
    private javax.swing.JCheckBox checkBoxIgnoreElNameInSimilarity;
    private javax.swing.JCheckBox checkBoxIgnoreElementOrder;
    private javax.swing.JCheckBox checkBoxIgnoreNamespaceURI;
    private javax.swing.JCheckBox checkBoxIgnorePrefix;
    private javax.swing.JCheckBox checkBoxIgnoreProcessingInstructions;
    private javax.swing.JCheckBox checkBoxIgnoreText;
    private javax.swing.JCheckBox checkBoxIgnoreWhitespaceOnlyText;
    private javax.swing.JCheckBox checkBoxTrimWhiteSpace;
    private javax.swing.JCheckBox jCheckBox4;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JSeparator jSeparator3;
    private javax.swing.JLabel leftFileLabel;
    private javax.swing.JLabel optionsLabel;
    private javax.swing.JTextField pathfileLeft;
    private javax.swing.JTextField pathfileRight;
    private javax.swing.JLabel rightFileLabel;
    private javax.swing.JButton runButton;
    private javax.swing.JLabel selectFilesLabel;
    // End of variables declaration//GEN-END:variables
}
